package com.sghd.fight.module.game.service.room;

import com.sghd.common.utils.ManagedException;
import com.sghd.common.utils.math.RandomUtils;
import com.sghd.fight.module.game.core.Grid;
import com.sghd.fight.module.game.core.Magic;
import com.sghd.fight.module.game.core.model.BattleSkill;
import com.sghd.fight.module.game.core.model.EliminateResult;
import com.sghd.fight.module.game.core.model.Unit;
import com.sghd.fight.module.game.core.model.UnitState;
import com.sghd.fight.module.game.event.PushEvent;
import com.sghd.fight.module.game.service.skill.ConfigService;
import com.sghd.fight.module.game.service.work.RoomRunner;
import com.sghd.fight.module.game.service.work.RoomTimer;
import com.sghd.fight.module.game.service.work.RoomWork;
import com.sghd.fight.net.SocketEnum;
import com.sghd.pojo.fight.game.*;

import java.util.*;

/**
 * @author frank
 * @date 2018-10-22 17:25
 * @desc
 **/
public class PvpRoom extends IRoom {
    private int scene;

    public PvpRoom(long id, RoomType type, RoomTimer timer, ConfigService configService) {
        super(id, type, timer, configService, System.currentTimeMillis());
    }

    @Override
    public EliminateResult move(long playerId, int first, int second) {
        EliminateResult result = super.move(playerId, first, second);
        return result;
    }

    @Override
    public void execute(long playerId, int skillId) {
        Unit unit = units.get(playerId);
        if (unit.hasState(UnitState.TRUSTEE)) {
            throw new ManagedException(-1, "玩家正在托管中！");
        }
        if (current.getId() != unit.getId()) {
            logger.debug("current[{}],player[{}]", current.getId(), playerId);
            throw new ManagedException(-1, "不是当前玩家回合！");
        }
        BattleSkill battleSkill = unit.getSkill(skillId);
        if (battleSkill == null) {
            throw new ManagedException(-1, "技能不存在");
        }
        //debuff导致技能无法使用
        if (unit.notUse()) {
            throw new ManagedException(-1, "当前无法使用！");
        }
        if (!battleSkill.canUse()) {
            throw new ManagedException(-1, "技能正在冷确中！");
        }
        Map<String, Object> ctx = new HashMap<>();
        SkillReport report = skilled(unit, skillId, ctx);
        //推送给客户端
        report.setDate(System.currentTimeMillis() + getConfig().getRoundTime());
        syncPost(PushEvent.NAME, PushEvent.valueOf(report, new ArrayList<>(units.keySet()), SocketEnum._EXECUTE_SKILL));
        super.execute(playerId, skillId);
    }

    @Override
    public RoomVo toVo() {
        RoomVo roomVo = new RoomVo();
        Date now = new Date();
        List<UnitVo> unitVos = new ArrayList<>();
        for (Unit player : units.values()) {
            if (player instanceof Robot) {
                timer.addTimer(new RoomWork(this, new RoomRunner() {
                    @Override
                    public void run(Date now) {
                        //机器人一段时间内自动准备
                        ready(player.getId());
                    }
                }, new Date(now.getTime() + RandomUtils.betweenInt(3000, 8000, true))));

            }
            unitVos.add(((Player) player).toVo());
        }
        roomVo.setMagic_Max(Magic.magic_Max);
        roomVo.setPlayers(unitVos);
        roomVo.setSeed(chessBoard.getRandom().getSeed());
        long startTime = now.getTime() + getConfig().getRoundTime();
        timer.addTimer(new RoomWork(this, new RoomRunner() {
            @Override
            public void run(Date now) {
                start();
            }
        }, new Date(now.getTime() + getConfig().getRoundTime())));
        roomVo.setStartTime(startTime);
        //生成棋盘
        chessBoard.genarete();
        return roomVo;
    }

    public RoomVo reconn(long playerId) {
        if (isOver()) {
            throw new ManagedException(-1, "房间已经结束！");
        }
        Unit unit = units.get(playerId);
        //取消托管状态
        if (unit.hasState(UnitState.TRUSTEE)) {
            endTrustee(playerId);
        }
        RoomVo roomVo = new RoomVo();
        roomVo.setScene(scene);
        List<GridVo> gridVos = new ArrayList<>();
        for (Grid grid : chessBoard.getGrids()) {
            gridVos.add(grid.toVo());
        }
        //棋盘
        roomVo.setGrids(gridVos);
        roomVo.setSeed(chessBoard.getRandom().getSeed());
        if (current == null) {
            roomVo.setCurrent(-1L);
        } else {
            roomVo.setCurrent(current.getId());
        }
        if (roomWork != null) {
            //结束时间
            roomVo.setStartTime(roomWork.getEnd().getTime());
        }
        roomVo.setMagic_Max(Magic.magic_Max);
        List<UnitVo> unitVos = new ArrayList<>();
        for (Unit unit_ : units.values()) {
            UnitVo unitVo = ((Player) unit_).reconn();
            unitVos.add(unitVo);
        }
        roomVo.setPlayers(unitVos);
        return roomVo;
    }

    @Override
    public void checkAndCollect(EliminateResult result, Unit unit) {
        super.checkRound(result, unit);
        super.collect(result, unit);
    }

    public void resetSkill(Long playerId, Set<Integer> keeps) {
        if (state == BEGIN) {
            throw new ManagedException(-1, "游戏已经开始，不允许更换技能");
        }
        Player player = (Player) units.get(playerId);
        player.resetSkill(keeps);
    }

    public void setScene(int scene) {
        this.scene = scene;
    }

    public int getScene() {
        return scene;
    }
}
